
/**
 *  \file hci_internal.h
 *
 *  This Header file contains the Data Structures, and Type Definitions used
 *  internally in the Mindtree Bluetooth HCI Layer.
 */

/*
 *  Copyright (C) 2013. Mindtree Ltd.
 *  All rights reserved.
 */

#ifndef _H_HCI_INTERNAL_
#define _H_HCI_INTERNAL_

/* ----------------------------------------------- Header File Inclusion */
/* EtherMind Common Header Files */
#include "BT_common.h"
#include "BT_bottom_half.h"

/* HCI & SM API Header Files */
#include "BT_hci_api.h"
#include "BT_sm_api.h"
#include "BT_device_queue.h"

/* Other Module Header Files */
#include "hci_transport.h"
#include "l2cap.h"
#include "sm.h"

#ifdef SMP
#include "BT_smp_api.h"
#include "smp.h"
#endif /* SMP */

#ifdef GATT_DB
#include "BT_gatt_db_api.h"
#endif /* GATT_DB */

/* HCI Header Files */
#include "hci_h.h"
#include "hci_defines.h"
#include "hci_dev_attr.h"

#ifdef HCI_LE_HAVE_ACL_TO_CIS_MAPPING
/* Currently bitarry data strucutre is used in HCI for CIS only */
#include "bitarray.h"
#endif /* HCI_LE_HAVE_ACL_TO_CIS_MAPPING */

/* ----------------------------------------------- HCI Debug Macros */
#ifndef HCI_NO_DEBUG
#define HCI_ERR(...)    BT_debug_error(BT_MODULE_ID_HCI, __VA_ARGS__)
#else  /* HCI_NO_DEBUG */
#define HCI_ERR         BT_debug_null
#endif /* HCI_NO_DEBUG */

#ifdef HCI_DEBUG

#define HCI_TRC(...)    BT_debug_trace(BT_MODULE_ID_HCI, __VA_ARGS__)
#define HCI_INF(...)    BT_debug_info(BT_MODULE_ID_HCI, __VA_ARGS__)

#define HCI_debug_dump_bytes(data, datalen) BT_debug_dump_bytes(BT_MODULE_ID_HCI, (data), (datalen))

#else /* HCI_DEBUG */

#define HCI_TRC         BT_debug_null
#define HCI_INF         BT_debug_null

#define HCI_debug_dump_bytes(data, datalen)

#endif /* HCI_DEBUG */

#ifdef HCI_DDEBUG

    #define HCID_TRC(...)    BT_debug_trace(BT_MODULE_ID_HCI, __VA_ARGS__)

#else /* HCI_DDEBUG */

    #define HCID_TRC    BT_debug_null

#endif /* HCI_DDEBUG */


/* ----------------------------------------------- Global Definitions */

/** Device Role - Unkown */
#define BT_DEVICE_ROLE_UNKNOWN                  0x02

/** HCI Connection Entity State Values */
#define HCI_CONNECTED                           0x01
#define HCI_DISCONNECTED                        0x02
#define HCI_W4_USER_RESPONSE                    0x03
#define HCI_W4_ACCEPT_COMPLETE                  0x04
#define HCI_W4_REJECT_COMPLETE                  0x05
#define HCI_W4_CONNECT_STATUS                   0x06
#define HCI_W4_CONNECT_COMPLETE                 0x07
#define HCI_W4_DISCONNECT_COMPLETE              0x08

/** Header Sizes */
#define ACL_DATA_HEADER_LEN                     4
#define SCO_DATA_HEADER_LEN                     3

/** Max Connection Entities per Remote Device */
#define HCI_MAX_CONNECTION_ENTITY               (1 + HCI_MAX_SCO_CHANNELS)

/** Host Controller to Host Flow Control */
#define HCI_MAX_SCO_RECV_LENGTH                 255
#define HCI_MAX_SCO_RECV_PACKETS                1
#define HCI_MAX_ACL_RECV_LENGTH                 800
#define HCI_MAX_ACL_RECV_PACKETS                1

/** Maximum Number of EIR Fields */
#ifdef BT_EIR
#define HCI_EIR_MAX_FIELDS                      80
#endif /* BT_EIR */

/** HCI Device Mode Values - Active/Hold/Sniff/Park */
#define HCI_ACTIVE_MODE                         BT_HCI_ACTIVE_MODE
#define HCI_HOLD_MODE                           BT_HCI_HOLD_MODE
#define HCI_SNIFF_MODE                          BT_HCI_SNIFF_MODE
#define HCI_PARK_MODE                           BT_HCI_PARK_MODE

/** HCI Initialization States */
/* Init state - set on ethermind init and bluetooth off */
#define BT_HCI_STATE_INIT                       0x00
/* ON Complete state - informed to the application */
#define BT_HCI_STATE_ON_COMPLETE                0x01
/* Indicate ON Complete state - intermediate state to inform application */
#define BT_HCI_STATE_ON_COMPLETE_IND            0x02

/** Number of valid HCI Events */
#ifdef BT_4_1
    #define HCI_MAX_EVENT_CODE                  0x57
#elif (defined BT_4_0 || defined BT_2_1_EDR)
    #define HCI_MAX_EVENT_CODE                  0x3D
#elif defined BT_HCI_1_2
    #define HCI_MAX_EVENT_CODE                  0x2D
#else  /* BT_HCI_1_2 */
    #define HCI_MAX_EVENT_CODE                  0x20
#endif /* BT_HCI_1_2 */

/** Number of valid HCI LE Subevent codes */
#ifdef BT_5_2
    #define HCI_LE_MAX_SUBEVENT_CODE           0x22
#elif defined BT_5_1
    #define HCI_LE_MAX_SUBEVENT_CODE           0x18
#elif defined BT_5_0
    #define HCI_LE_MAX_SUBEVENT_CODE           0x14
#elif defined BT_4_2
    #define HCI_LE_MAX_SUBEVENT_CODE           0x0B
#elif defined BT_4_1
    #define HCI_LE_MAX_SUBEVENT_CODE           0x06
#elif defined BT_4_0
    #define HCI_LE_MAX_SUBEVENT_CODE           0x05
#endif /* BT_4_0 */

#ifdef HCI_HAVE_INIT_COMMAND_MASK
/** Bitmap values for HCI BT-Init Command Mask */
#define HCI_INIT_COMMAND_MASK_RESET             0x00000001

/** Maximum & Default Bitmap values for HCI BT-Init Command Mask */
#define HCI_INIT_COMMAND_MASK_VALUE_DEFAULT     0x00000000
#define HCI_INIT_COMMAND_MASK_VALUE_MAX         0x00000001
#endif /* HCI_HAVE_INIT_COMMAND_MASK */


/* ----------------------------------------------- Structures/Data Types */

/** HCI Command Parameters */
typedef struct
{
    void *param_1;
    void *param_2;
    void *param_3;
    void *param_4;
    void *param_5;
    void *param_6;
    void *param_7;
    void *param_8;

#ifdef BT_4_0
    void *param_9;
    void *param_10;
    void *param_11;
    void *param_12;
#endif /* BT_4_0 */
} HCI_COMMAND_PARAMS;


/** The HCI Connection Entity */
typedef struct hci_ce_struct
{
    /** Connection Handle */
    UINT16 handle;

    /** Encryption Mode for this Connection Handle */
    UCHAR encryption_mode;

    /** State of this Connection */
    UCHAR state;

    /** Link Type - ACL/SCO/eSCO */
    UCHAR link_type;

    /** Role - Master/Slave */
    UCHAR role;

} HCI_CE;


/**
 *  Structure to Store information about the Remote Devices.
 *  The information of any device is stored during incoming and
 *  outgoing connections.
 */
typedef struct remote_device_struct
{
    /**
     *  ACL or SCO Connection Entities to this Device - There can be one
     *  ACL Link and a maximum of 3 SCO Links per pair of Bluetooth devices.
     *    Index 0 - ACL Connection Entity.
     *    Index 1, 2, 3 and rest - SCO Connection Entities.
     */
    HCI_CE connection_entity [ HCI_MAX_CONNECTION_ENTITY ];

#ifdef HCI_LE_HAVE_ACL_TO_CIS_MAPPING
    /** Bitarry to maintain associated CIS mapping */
    UINT32 cis_bitarray[BITARRAY_NUM_BLOCKS(HCI_MAX_CIS_CONNECTIONS)];
#endif /* HCI_LE_HAVE_ACL_TO_CIS_MAPPING */

    /** Remote Device Identification */
    DEVICE_HANDLE device_handle;

    /** Current Mode of Operation for this Device */
    UCHAR current_mode;

    /** Number of Active Connections to this Device */
    UCHAR no_of_connection;

} REMOTE_DEVICE;


/** HCI Command Queue */
typedef struct
{
    /* "Allocated" Data Pointer */
    UCHAR *allocated_data;

    /*
     *  Data Length. If data length is zero, the element is considered
     *  invalid.
     */
    UINT16 data_length;

    /* Flag to denote allocated/free status */
    UCHAR valid;

    /* Static Data Pointer */
    BT_DEFINE_STATIC_DATA(static_data)

} HCI_COMMAND_Q_ELEMENT;

#ifdef HCI_SUPPORT_LE_CONN_FAILURE_EVENT_WITH_NO_ADDR
/** HCI LE Connection Information */
typedef struct _HCI_LE_CONNECT_REQ_INFO
{
    /**
     * Remote Device Data Structure associated with the peer device
     * being attempted to get connected
     */
    REMOTE_DEVICE * device;

} HCI_LE_CONNECT_REQ_INFO;
#endif /* HCI_SUPPORT_LE_CONN_FAILURE_EVENT_WITH_NO_ADDR */

#ifdef HCI_ISO_DATA
/** HCI ISO Data Queue */
typedef struct
{
    /* "Allocated" Data Pointer */
    UCHAR *allocated_data;

    /*
     *  Data Length. If data length is zero, the element is considered
     *  invalid.
     */
    UINT16 data_length;

    /* Flag to denote allocated/free status */
    UCHAR valid;

    /* Connection Handle */
    UINT16 connection_handle;

} HCI_ISO_DATA_Q_ELEMENT;
#endif /* HCI_ISO_DATA */

#ifdef HCI_LE_EXT_ADV_SETS_LOCAL_ADDR_SUPPORT
/**
 *  Structure to Store information about the Extended ADV related
 *  meta parameters w.r.t Advertising Handles.
 *  The information is stored during handling of
 *  - Extended ADV Parameter Setting Command
 *  - Set ADV Set's Random Address Command
 *  - ADV set terminated event
 */
typedef struct ext_adv_meta_param_struct
{
    /** Advertising Handle */
    UCHAR adv_hndl;

    /** Own Address Type and Address */
    BT_DEVICE_ADDR l_addr;

    /** Advertising Event Properties */
    UINT16 adv_evt_prpty;

} HCI_EXT_ADV_META_PARAM;
#endif /* HCI_LE_EXT_ADV_SETS_LOCAL_ADDR_SUPPORT */

#ifdef HCI_LE_CIG_CIS_SUPPORT
/** The HCI LE CIS Connection Entity */
typedef struct hci_le_cis_ce_struct
{
    /** Remote Device Index */
    UCHAR     hci_remote_devices_index;

    /** CIS Connection Handle */
    UINT16    cis_handle;

    /** State of this Connection */
    UCHAR     state;

    /** Role - Master/Slave */
    UCHAR     role;

} HCI_LE_CIS_CE;
#endif /* HCI_LE_CIG_CIS_SUPPORT */

/* ----------------------------------------------- Global Macros */
/** Declaring HCI Event Handlers */
#define HCI_EVENT_HANDLER(x)    void (x) (UCHAR *, UINT16)

#ifndef HCI_NO_NULL_PARAM_CHECK
/** Null Check of HCI API Parameters */
#define hci_null_check(x) \
        if (NULL == (x)) \
        { \
            HCI_ERR( \
            "[HCI] NULL Pointer detected. Referrence Impossible\n"); \
            return HCI_NULL_PARAMETER_NOT_ALLOWED; \
        }
#else
#define hci_null_check(x)
#endif /* HCI_NO_NULL_PARAM_CHECK */

#ifndef HCI_NO_RANGE_CHECK
/** Range Check for HCI API Parameters */
#define hci_range_check_start(param, start) \
        if ( ! ((param) >= (start)) ) \
        { \
            HCI_ERR( \
            "[HCI] HCI Range Check FAILED\n"); \
            return HCI_PARAMETER_OUTSIDE_RANGE; \
        }

#define hci_range_check_end(param, end) \
        if ( ! ((param) <= (end)) ) \
        { \
            HCI_ERR( \
            "[HCI] HCI Range Check FAILED\n"); \
            return HCI_PARAMETER_OUTSIDE_RANGE; \
        }

#define hci_range_check(param, start, end) \
        if ( ! ( ((param) >= (start)) && ((param) <= (end)) ) ) \
        { \
            HCI_ERR( \
            "[HCI] HCI Range Check FAILED\n"); \
            return HCI_PARAMETER_OUTSIDE_RANGE; \
        }

/** Range Check for Connection Handles (0x0000 - 0x0EFF) */
#define hci_connection_handle_range_check(handle) \
        hci_range_check_end((handle), 0x0EFF)
#else
#define hci_range_check_start(param, start)
#define hci_range_check_end(param, end)
#define hci_range_check(param, start, end)
#define hci_connection_handle_range_check(handle)
#endif /* HCI_NO_RANGE_CHECK */


/** HCI Dynamic Memory Allocation and Release Macros */
#define hci_malloc      BT_alloc_mem
#define hci_free        BT_free_mem


/** To Lock HCI Global Mutex */
#define HCI_MUTEX_LOCK()               BT_MUTEX_LOCK(hci_mutex, HCI)

/** To Unlock HCI Global Mutex */
#define HCI_MUTEX_LOCK_VOID()          BT_MUTEX_LOCK_VOID(hci_mutex, HCI)

/** To Lock HCI Global Mutex */
#define HCI_MUTEX_UNLOCK()             BT_MUTEX_UNLOCK(hci_mutex, HCI)

/** To Unlock HCI Global Mutex */
#define HCI_MUTEX_UNLOCK_VOID()        BT_MUTEX_UNLOCK_VOID(hci_mutex, HCI)

#ifdef HCI_LE_CIG_CIS_SUPPORT
/** To free CIS Connection Entity */
#define HCI_LE_FREE_CIS_CE(ce) \
        (ce).hci_remote_devices_index = BT_MAX_REMOTE_DEVICES; \
        (ce).cis_handle               = HCI_INVALID_CONNECTION_HANDLE; \
        (ce).state                    = HCI_DISCONNECTED; \
        (ce).role                     = BT_DEVICE_ROLE_UNKNOWN;
#endif /* HCI_LE_CIG_CIS_SUPPORT */

#ifdef HCI_ISO_DATA
#define hci_form_iso_data_packet_header(buffer, handle, pb, ts, length) \
    (buffer)[0] = (UCHAR)(handle);\
    (buffer)[1] = (UCHAR)((handle) >> 8);\
    (buffer)[1] = (((buffer)[1])|((pb) << 4));\
    (buffer)[1] = (((buffer)[1])|((UCHAR)(ts) << 6));\
    (buffer)[2] = (UCHAR)(length);\
    (buffer)[3] = (UCHAR)((length) >> 8);
#endif /* HCI_ISO_DATA */

/* ----------------------------------------------- HCI-SM Macros */
/** To indicate ACL Connection Request to SM */
#define hci_sm_acl_connection_request(bd, cod) \
        sm_acl_connection_request ((bd), (cod));

/** To indicate ACL Create Connection to SM */
#define hci_sm_acl_create_connection(bd) \
        sm_acl_create_connection ((bd));

/** To indicate ACL Connection Completion to SM */
#define hci_sm_acl_connection_complete(bd, status, handle, mode) \
        sm_acl_connection_complete ((bd), (status), (handle), (mode));

/** To indicate Command Status Events to SM */
#define hci_sm_handle_command_status(opcode, status) \
        HCI_MUTEX_UNLOCK_VOID(); \
        sm_hci_error_indication ((opcode), (UINT16)(status)); \
        HCI_MUTEX_LOCK_VOID();

/* To indicate Command Complete to SM */
#define hci_sm_command_complete_event(packet) \
        HCI_MUTEX_UNLOCK_VOID(); \
        sm_command_complete_event(packet); \
        HCI_MUTEX_LOCK_VOID();

#if (BT_MAX_REMOTE_DEVICES == 1)
#ifdef BT_DUAL_MODE
/** Remote Device List Management Functions */
#define hci_find_remote_device(bd,hndl,type) \
        (((hci_remote_devices[0].no_of_connection != 0) && \
          (API_SUCCESS == device_queue_search_remote_addr(hndl, bd, type)) && \
          ((*hndl) == hci_remote_devices[0].device_handle))? \
         &hci_remote_devices[0]: NULL)
#else /* BT_DUAL_MODE */
#define hci_find_remote_device(bd,hndl) \
        (((hci_remote_devices[0].no_of_connection != 0) && \
          (API_SUCCESS == device_queue_search_remote_addr(hndl, bd)) && \
          ((*hndl) == hci_remote_devices[0].device_handle))? \
         &hci_remote_devices[0]: NULL)
#endif /* BT_DUAL_MODE */
#endif /* BT_MAX_REMOTE_DEVICES == 1 */

#define HCI_RPA_IN_PROGRESS() \
        ((HCI_INVALID_CONNECTION_HANDLE != hci_resolution_conn_handle)? \
        (BT_TRUE): (BT_FALSE))

#ifdef BT_5_0
#define HCI_LE_META_EVENT_TO_BE_ENQUEUED(le_subevent) \
        (((HCI_LE_CONNECTION_COMPLETE_SUBEVENT == (le_subevent)) ||\
          (HCI_LE_LONG_TERM_KEY_REQUESTED_SUBEVENT == (le_subevent)) ||\
          (HCI_LE_CONNECTION_UPDATE_COMPLETE_SUBEVENT == (le_subevent)) ||\
          (HCI_LE_ENHANCED_CONNECTION_COMPLETE_SUBEVENT == (le_subevent)) ||\
          (HCI_LE_REMOTE_CONN_PARAM_REQ_SUBEVENT == (le_subevent)) ||\
          (HCI_LE_DATA_LENGTH_CHANGE_SUBEVENT == (le_subevent)) ||\
          (HCI_LE_PHY_UPDATE_COMPLETE_SUBEVENT == (le_subevent)) ||\
          (HCI_LE_ADVERTISING_SET_TERMINATED_SUBEVENT == (le_subevent)) ||\
          (HCI_LE_CHANNEL_SELECTION_ALGORITHM_SUBEVENT == (le_subevent)))?\
         (BT_TRUE): (BT_FALSE))
#else
/* For 4.2 */
#define HCI_LE_META_EVENT_TO_BE_ENQUEUED(le_subevent) \
        (((HCI_LE_CONNECTION_COMPLETE_SUBEVENT == (le_subevent)) ||\
          (HCI_LE_LONG_TERM_KEY_REQUESTED_SUBEVENT == (le_subevent)) ||\
          (HCI_LE_CONNECTION_UPDATE_COMPLETE_SUBEVENT == (le_subevent)) ||\
          (HCI_LE_ENHANCED_CONNECTION_COMPLETE_SUBEVENT == (le_subevent)) ||\
          (HCI_LE_REMOTE_CONN_PARAM_REQ_SUBEVENT == (le_subevent)) ||\
          (HCI_LE_DATA_LENGTH_CHANGE_SUBEVENT == (le_subevent)))?\
         (BT_TRUE): (BT_FALSE))
#endif /* BT_5_0 */

/** Macro to Construct the HCI SCO Data Packet Header */
/* Host shall set Packet Status Flag as 0 */
#define hci_form_sco_packet_header(buffer, handle, psf, length) \
    (buffer)[0] = (UCHAR)(handle);\
    (buffer)[1] = (UCHAR)((handle) >> 8);\
    (buffer)[2] = (UCHAR)(length)

/** Macro to Extract from the HCI SCO Data Packet Header */
#define hci_extract_sco_packet_header(buffer, handle, psf, length) \
    (handle) = ((buffer)[1] << 8); \
    (handle) |= (buffer)[0]; \
    (handle) &= 0x0FFF; \
    (psf) = (0x0003 & ((buffer)[1] >> 4)); \
    (length) = (buffer)[2];

/* ----------------------------------------------- HCI-SMP Macros */
#if (defined BT_4_0 && defined SMP)

/** To indicate Connection Completion to SMP */
#define hci_smp_connection_complete(bd, status, handle, role) \
        smp_connection_complete ((bd), (status), (handle), (role))

/** To indicate Cisconnection Completion to SMP */
#define hci_smp_disconnection_complete(handle) \
        smp_disconnection_complete ((handle))

/** To indicate Command Complete to SMP */
#define hci_smp_command_complete(packet) \
        smp_command_complete (packet)

/** To indicate Command Status to SMP */
#define hci_smp_command_status(packet) \
        smp_command_status (packet)

#endif /* (defined BT_4_0 && defined SMP) */

#if ((defined BT_5_1) && (defined GATT_DB))
/** To indicate Command Complete to GATT DB Interface */
#define hci_gatt_db_command_complete(packet) \
        gatt_db_handle_hci_command_complete (packet)
#endif /* BT_5_1 && GATT_DB */

/* ----------------------------------------------- Internal Functions */
/** Function to handle initilization sequence in Non-Blocking mode */
void hci_handle_init_sequence
     (
         UINT16 opcode,
         UCHAR status
     );

#ifdef BT_DUAL_MODE

/** Remote Device List Management Functions */
#if (BT_MAX_REMOTE_DEVICES > 1)
REMOTE_DEVICE * hci_find_remote_device
                (
                    BT_DEVICE_ADDR * bd_addr,
                    DEVICE_HANDLE *handle,
                    UCHAR type
                );
#endif /* BT_MAX_REMOTE_DEVICES > 1 */

REMOTE_DEVICE *hci_alloc_remote_device(BT_DEVICE_ADDR *bd_addr, UCHAR type, UCHAR privacy);

#define hci_find_br_edr_remote_device(b,h)\
        hci_find_remote_device ((b),(h),DQ_BR_LINK)

#define hci_find_le_remote_device(b,h)\
        hci_find_remote_device ((b),(h),DQ_LE_LINK)

#define hci_find_any_remote_device(b,h)\
        hci_find_remote_device ((b),(h),DQ_LINK_ANY)

#define hci_alloc_br_edr_remote_device(b)\
        hci_alloc_remote_device ((b), DQ_BR_LINK, 0x00)

#define hci_alloc_le_remote_device(b, p)\
        hci_alloc_remote_device ((b), DQ_LE_LINK, (p))

#else /* BT_DUAL_MODE */

/** Remote Device List Management Functions */
#if (BT_MAX_REMOTE_DEVICES > 1)
REMOTE_DEVICE * hci_find_remote_device
                (
                    BT_DEVICE_ADDR * bd_addr,
                    DEVICE_HANDLE *handle
                );
#endif /* BT_MAX_REMOTE_DEVICES > 1 */

REMOTE_DEVICE *hci_alloc_remote_device(BT_DEVICE_ADDR *bd_addr);

#define hci_find_br_edr_remote_device(b,h)\
        hci_find_remote_device ((b),(h))

#define hci_find_le_remote_device(b,h)\
        hci_find_remote_device ((b),(h))

#define hci_find_any_remote_device(b,h)\
        hci_find_remote_device ((b),(h))

#define hci_alloc_br_edr_remote_device(b)\
        hci_alloc_remote_device ((b))

#define hci_alloc_le_remote_device(b)\
        hci_alloc_remote_device ((b))

#endif /* BT_DUAL_MODE */

void hci_free_remote_device(REMOTE_DEVICE *device);

HCI_CE *hci_get_ce
       (
           REMOTE_DEVICE *device,
           UCHAR link_type,
           UCHAR state
       );

REMOTE_DEVICE *hci_find_device_by_handle
              (
                  UINT16 connection_handle,
                  HCI_CE **ce
              );

/** HCI connection & disconnection routines */
API_RESULT hci_sco_connection
           (
               UCHAR *packet,
               UINT16 length
           );

#ifdef BT_HCI_1_2
#ifdef HCI_ENH_SCO
void hci_enh_sco_pack_connection_params
     (
         UCHAR              * buffer,
         HCI_ENH_SCO_PARAMS * enh_sco_params
     );
#endif /* HCI_ENH_SCO */
#endif /* BT_HCI_1_2 */

#ifdef HCI_LE_CIG_CIS_SUPPORT
UINT8 hci_find_cis_entity_by_handle
      (
          UINT16     cis_handle
      );

UINT8 hci_find_cis_entity_by_state
      (
          UINT8     cis_state
      );

API_RESULT hci_find_and_alloc_cis_entity
           (
               UINT16     acl_handle,
               UINT16     cis_handle,
               UINT8    * remote_dev_index,
               UINT8    * cis_free_entity_index
           );
#endif /* HCI_LE_CIG_CIS_SUPPORT */

#ifdef HCI_LE_HAVE_ACL_TO_CIS_MAPPING
void hci_generate_cis_disc_on_acl_disconnection
     (
         REMOTE_DEVICE *  device
     );
#else
#define hci_generate_cis_disc_on_acl_disconnection(device)
#endif /* HCI_LE_HAVE_ACL_TO_CIS_MAPPING */

/** Handling Incoming HCI Events from HC */
HCI_EVENT_HANDLER( hci_connection_complete_event );
HCI_EVENT_HANDLER( hci_connection_request_event );
HCI_EVENT_HANDLER( hci_disconnection_complete_event );
HCI_EVENT_HANDLER( hci_command_complete_event );
HCI_EVENT_HANDLER( hci_command_status_event );
HCI_EVENT_HANDLER( hci_hardware_error_event );
HCI_EVENT_HANDLER( hci_number_of_completed_packets_event );
HCI_EVENT_HANDLER( hci_link_key_pin_code_request_event );
HCI_EVENT_HANDLER( hci_link_key_notification_event );
HCI_EVENT_HANDLER( hci_auth_complete_encrypt_change_event );
HCI_EVENT_HANDLER( hci_mode_change_event );
HCI_EVENT_HANDLER( hci_change_connection_link_key_complete_event );
HCI_EVENT_HANDLER( hci_unimplemented_event );

#ifdef BT_SSP
HCI_EVENT_HANDLER( hci_io_capability_event );
#endif /* BT_SSP */

#ifdef BT_SSP_UC
HCI_EVENT_HANDLER( hci_user_confirmation_request_event );
#endif /* BT_SSP_UC */

#ifdef BT_SSP_PE
HCI_EVENT_HANDLER( hci_user_passkey_request_event );
HCI_EVENT_HANDLER( hci_user_passkey_notification_event );
#endif /* BT_SSP_PE */

#ifdef BT_SSP_OOB
HCI_EVENT_HANDLER( hci_remote_oob_data_request_event );
#endif /* BT_SSP_OOB */

/** Handling Incoming HCI LE Subevents from HC */
#ifdef BT_4_0
HCI_EVENT_HANDLER( hci_le_connection_complete_event );
HCI_EVENT_HANDLER( hci_le_long_term_key_requested_event );
#endif /* BT_4_0 */

#ifdef BT_4_2
HCI_EVENT_HANDLER(hci_le_p256_pub_key_read_complete_event);
HCI_EVENT_HANDLER(hci_le_gen_dhkey_complete_event);
HCI_EVENT_HANDLER(hci_le_enhanced_connection_complete_event);
#endif /* BT_4_2 */

#ifdef HCI_LE_ADVERTISING_EXTENSION_SUPPORT
HCI_EVENT_HANDLER(hci_le_ext_adv_set_terminated_event);
#endif /* HCI_LE_ADVERTISING_EXTENSION_SUPPORT */

#ifdef HCI_LE_CIG_CIS_SUPPORT
HCI_EVENT_HANDLER(hci_le_cis_established_event);
HCI_EVENT_HANDLER(hci_le_cis_request_event);
#endif /* HCI_LE_CIG_CIS_SUPPORT */

/* Additional Event specific Handling */
void hci_handle_hardware_error
     (
         void
     );

/** HCI/SM Automatic Mode - HCI Responses */
API_RESULT hci_connection_response
           (
               UINT16 opcode,
               UCHAR  *bd_addr,
               UCHAR  role_or_reason
           );

void hci_handle_connection_command_status
     (
         UINT16    opcode,
         UCHAR     status
     );

#ifdef HCI_LE_CIG_CIS_SUPPORT
void hci_handle_create_cis_command_status
     (
         UINT16    opcode,
         UCHAR     status
     );

void hci_handle_accept_cis_command_status
     (
         UINT16    opcode,
         UCHAR     status
     );

void hci_handle_reject_cis_command_complete
     (
         UINT16    opcode,
         UINT16    cis_handle,
         UCHAR     status
     );
#endif /* HCI_LE_CIG_CIS_SUPPORT */

/* HCI originated Command Handlers */
API_RESULT hci_host_number_of_completed_packets
           (
               UINT16 connection_handle,
               UINT16 num_completed
           );


/* HCI Command Formation, Enqueueing & Management */
API_RESULT hci_trigger_command_tx
           (
               void
           );

API_RESULT hci_command_enqueue
           (
               UINT16 opcode,
               UCHAR length,
               UCHAR * packet
           );

/* HCI ISO Data handling, Enqueueing & Management */
API_RESULT hci_trigger_iso_data_tx
           (
               void
           );

API_RESULT hci_iso_data_enqueue
           (
               UINT16  connection_handle,
               UINT16  length,
               UCHAR * packet
           );

/* Common API Handler */
API_RESULT hci_common_api_handler
           (
               UINT16                  opcode,

               UINT16                  packet_len,
               HCI_COMMAND_PARAMS *    params
           );

API_RESULT hci_common_api_handler_ext
           (
               UINT16     opcode,
               UINT16     packet_len,
               UCHAR *    params
           );

#ifdef HCI_DISCONNECT_SUPPORT
API_RESULT hci_disconnect_req
           (
               UINT16    connection_handle,
               UCHAR     reason
           );
#endif /* HCI_DISCONNECT_SUPPORT */

#ifdef HOST_RESOLVE_PVT_ADDR
void hci_le_enqueue_packet (UCHAR type, UCHAR * packet, UINT16 length);
void hci_le_deliver_packets (void);
#endif /* HOST_RESOLVE_PVT_ADDR */

#ifdef HCI_DEBUG_DB
void hci_dump_data_structures ( void );
#endif /* HCI_DEBUG_DB */

#ifdef HOST_RESOLVE_PVT_ADDR
void hci_le_conn_resolution_complete (SMP_RPA_RESOLV_INFO * rpa_info, UINT16 status);
#endif /* HOST_RESOLVE_PVT_ADDR */

#ifdef HCI_LE_EXT_ADV_SETS_LOCAL_ADDR_SUPPORT
/**
 *  hci_le_find_ext_adv_set:
 *  This function gives the index of the current ADV Handle requested
 *  which is maintained in the Stack.
 *
 *  @param: (IN) UCHAR adv_handle: The advertisement handle.
 *
 *  @return: UCHAR : Index of a matching entry if found. Otherwise,
 *                   returns HCI_MAX_SUPPORTED_EXT_ADV_SETS as error.
 */
UCHAR hci_le_find_ext_adv_set(UCHAR adv_handle);

/**
 *  hci_le_find_free_ext_adv_set_entry:
 *  This function returns an index of empty place in the
 *  ext adv meta param list which is maintained in the Stack.
 *
 *  @return: UCHAR : Index of a free entity. Otherwise,
 *                   returns HCI_MAX_SUPPORTED_EXT_ADV_SETS as error.
 */
UCHAR hci_le_find_free_ext_adv_set_entry(void);

/**
 *  hci_le_remove_ext_adv_set:
 *  This function removes the ADV Handle requested
 *  from the list which is maintained in the Stack.
 *
 *  @param: (IN)  UCHAR adv_handle: The advertisement handle.
 *
 *  @return: API_RESULT : API_SUCCESS on successful removal.
 *                        Corresponding error on failure.
 */
API_RESULT hci_le_remove_ext_adv_set(UCHAR adv_handle);
#endif /* HCI_LE_EXT_ADV_SETS_LOCAL_ADDR_SUPPORT */

#endif /* _H_HCI_INTERNAL_ */

